/*
 * Jenny Ruppen 09-730-391
 * Sebastien Goldberg 08-914-855
 * Henry Raymond 08-928-061
 * Stefan Mussato 09-752-270
 */
 
package ch.uzh.ifi.sopra.gruppe9.game;

import java.util.ArrayList;

import ch.uzh.ifi.sopra.gruppe9.game.Scenery.Location;

import com.jme3.scene.Node;


/**
 * Interactive in-game screen of the bank.
 */
public class BankInterface extends Node {
	
	
	/**
	 * List of all registered mouseOver event elements of the bank.
	 */
	private ArrayList<IMouseOverable> mouseOverables = new ArrayList<IMouseOverable>();
	
	
	/**
	 * List of all registered click event elements of the bank.
	 */
	private ArrayList<IClickable> clickables = new ArrayList<IClickable>();
	
	
	/**
	 * Geometry node of all content of the window.
	 */
	private Node bank;
	
	
	/**
	 * Color constraint flag of the bank
	 */
	private GuiQuad colorConstraintIcon;
	
	
	/**
	 * Text telling player that it's not his turn
	 */
	private GuiText notYourTurn;

	
	/**
	 * Get money button
	 */
	private GuiButton getMoney;
	
	
	/**
	 * Close window button
	 */
	private GuiButton close;
	
	
	/**
	 * Selection of the amount of money the player wants from the bank.
	 */
	private GuiSelection amount;
	
	
	/**
	 * Parent node of all buying agents in the bank.
	 */
	private Node buyingAgentsNode;
	
	
	/**
	 * Window where the player can choose which buying agent he wants to use.
	 */
	private BuyingAgentInterface buyingAgentInterface;
	
	
	/**
	 * X coordinate offset of the money amount options.
	 */
	private static final int[] amountOffsetX = {134, 254, 374, 534};
	
	
	/**
	 * Constructor: Creates geometry.
	 */
	public BankInterface() {
		
		bank = new Node();
		
		GuiWindow window = new GuiWindow(GUI.Offset.SCENE, 29, 30, 710, 610, 50);
		bank.attachChild(window);
		
		GuiText title = new GuiText("Bank", Fonts.getLarge());
		title.setPositionSize(GUI.Offset.SCENE, (768 - (int)title.getLineWidth()) / 2, 60, 51);
		bank.attachChild(title);
		
		colorConstraintIcon = new GuiQuad();
		colorConstraintIcon.setPositionSize(GUI.Offset.SCENE, 269, 145, 80, 30, 51);
		colorConstraintIcon.setMaterial(MaterialManager.getColorConstraintFlags(), 0.0f, 0.0f, 1.0f, 0.2f);
		bank.attachChild(colorConstraintIcon.create());
		
		amount = new GuiSelection(true, false);
		
		for(int i = 0; i < 4; i++) {
			amount.addOption(i, GUI.Offset.SCENE, amountOffsetX[i], 195, 100, 140, 51);
			
			GuiQuad amountIcon = new GuiQuad();
			amountIcon.setPositionSize(GUI.Offset.SCENE, amountOffsetX[i] + 10, 215, 80, 120, 52);
			amountIcon.setMaterial(MaterialManager.getBankIcons(), 0.25f * i, 0.0f, 0.25f, 1.0f);
			bank.attachChild(amountIcon.create());
			
			if(i < 3) {
				GuiSlot slot = new GuiSlot(GUI.Offset.SCENE, amountOffsetX[i] + 30, 355, 40, 75, 51);
				bank.attachChild(slot);
			}			
		}

		bank.attachChild(amount);
		amount.setAction(new ICallback() {
			public void run() { 
				if(amount.getValue() == -1) {
					getMoney.setActive(false);
				} else {
					getMoney.setActive(true);
				}
			}
		});
		
		buyingAgentsNode = new Node();
		bank.attachChild(buyingAgentsNode);
		
		getMoney = new GuiButton("Geld beziehen");
		getMoney.setPositionSize(GUI.Offset.SCENE, (768 - 220) / 2, 450, 220, 51);
		getMoney.setAction(new ICallback() { 
			public void run() {
				getMoney.setActive(false);
				close.setActive(false);
				GUI.unregisterMouseOverable(mouseOverables);
				GUI.unregisterClickable(clickables);
				if(amount.getValue() != 3) {
					buyingAgentInterface = new BuyingAgentInterface(false, Game.board().getBank().getColorConstraint());
				} else {
					buyingAgentInterface = new BuyingAgentInterface(false, BuyingAgent.Color.NONE);
				}
				buyingAgentInterface.setCancelAction(new ICallback() { 
					public void run() {
						getMoney.setActive(true);
						close.setActive(true);
						GUI.registerMouseOverable(mouseOverables);
						GUI.registerClickable(clickables);
					}
				});
				buyingAgentInterface.setCarryOutActionAction(new ICallback() {
					public void run() {
						getMoney.setActive(true);
						close.setActive(true);
						GUI.registerMouseOverable(mouseOverables);
						GUI.registerClickable(clickables);
						int[] buyingAgentIDs = buyingAgentInterface.getBuyingAgents();
						
						boolean success = Game.board().getBank().doAction(Game.board().getMyIndex(), buyingAgentIDs[0], buyingAgentIDs[1], amount.getValue());
						if(!success) {
							System.err.println("Error while executing bank action.");
							return;
						}
						GUI.changeState(GuiState.State.CLEAN_INGAME_SCREEN);
					}
				});
			}
		});
		getMoney.create();
		getMoney.setActive(false);
		
		notYourTurn = new GuiText("Du bist nicht am Zug.");
		notYourTurn.setPositionSize(GUI.Offset.SCENE, (768 - (int)notYourTurn.getLineWidth()) / 2, 480, 51);
		
		close = new GuiButton("Schliessen");
		close.setPositionSize(GUI.Offset.SCENE, (768 - 160) / 2, 555, 160, 51);
		close.setAction(new ICallback() { 
			public void run() { 
				GUI.changeState(GuiState.State.CLEAN_INGAME_SCREEN);
			}
		});
		bank.attachChild(close.create());
		
		clickables.add(getMoney);
		clickables.add(close);
		clickables.addAll(amount.getClickables());
		
		mouseOverables.add(getMoney);
		mouseOverables.add(close);
		mouseOverables.addAll(amount.getMouseOverables());
		
	}
	
	
	/**
	 * Attach all needed geometry and register all mouseOver and click events.
	 */
	public void show() {
		Scenery.startCamAnimation(Location.BANK, new ICallback() {
			public void run() {
				GUI.getBank().attachChild(bank);
				GUI.registerMouseOverable(mouseOverables);
				GUI.registerClickable(clickables);
		
				GUI.getBank().updateBank();
			}
		});
	}
	
	
	/**
	 * Detach all geometry and unregister all mouseOver and click events.
	 */
	public void hide() {
		this.detachChild(bank);
		GUI.unregisterMouseOverable(mouseOverables);
		GUI.unregisterClickable(clickables);
		Scenery.startCamAnimation(Location.BASIC_SCENE_CAMERA, null);
	}


	/**
	 * Updates bank amount selection when the server sends a update message.
	 */
	public void updateBank() {
		amount.clearSelection();
		BuyingAgent.Color colorConstraint = Game.board().getBank().getColorConstraint();
		if(colorConstraint == BuyingAgent.Color.NONE && bank.hasChild(colorConstraintIcon)) {
			bank.detachChild(colorConstraintIcon);
		}
		if(colorConstraint != BuyingAgent.Color.NONE && !bank.hasChild(colorConstraintIcon)) {
			bank.attachChild(colorConstraintIcon);
		}
		if(colorConstraint == BuyingAgent.Color.BLUE) {
			colorConstraintIcon.changeTextureCoords(0.0f, 0.0f, 1.0f, 0.2f);
		} else if(colorConstraint == BuyingAgent.Color.GREEN) {
			colorConstraintIcon.changeTextureCoords(0.0f, 0.2f, 1.0f, 0.2f);
		} else if(colorConstraint == BuyingAgent.Color.ORANGE) {
			colorConstraintIcon.changeTextureCoords(0.0f, 0.4f, 1.0f, 0.2f);
		} else if(colorConstraint == BuyingAgent.Color.PURPLE) {
			colorConstraintIcon.changeTextureCoords(0.0f, 0.6f, 1.0f, 0.2f);
		} else if(colorConstraint == BuyingAgent.Color.YELLOW) {
			colorConstraintIcon.changeTextureCoords(0.0f, 0.8f, 1.0f, 0.2f);
		}
		
		int[] useOfSlots = Game.board().getBank().getBuyingAgentSlots();
		buyingAgentsNode.detachAllChildren();
		for(int i = 0; i < 3; i++) {
			if(useOfSlots[i] == 1) {
				buyingAgentsNode.attachChild(GuiBuyingAgent.getColor2D(colorConstraint, GUI.Offset.SCENE, amountOffsetX[i] + 30, 355, 52));
			} else if(useOfSlots[i] == 2) {
				buyingAgentsNode.attachChild(GuiBuyingAgent.getColor2D(BuyingAgent.Color.NONE, GUI.Offset.SCENE, amountOffsetX[i] + 30, 355, 52));
			}
		}
		
		if(Game.board().getTurn() == Game.board().getMyIndex()) {
			if(bank.hasChild(notYourTurn)) {
				bank.detachChild(notYourTurn);
			}
			if(!bank.hasChild(getMoney)) {
				bank.attachChild(getMoney);
			}
			amount.activateAll();
			for(int i = 0; i < 3; i++) {
				if(useOfSlots[i] == 1) {
					amount.deactivate(i);
				} else if(useOfSlots[i] == 2) {
					amount.deactivate(i);
				}
			}
		} else {
			if(!bank.hasChild(notYourTurn)) {
				bank.attachChild(notYourTurn);
			}
			if(bank.hasChild(getMoney)) {
				bank.detachChild(getMoney);
			}
			amount.deactivateAll();
		}
	}
	
}
